/*
 * @Author: Ma Yuchen
 * @Date: 2022-11-22 21:03:02
 * @LastEditors: Ma YuChen
 * @LastEditTime: 2022-11-30 20:58:26
 * @Description: file content
 * @FilePath: \BootLoader\main.c
 */
#include <gd32f4xx.h>
#include "menu.h"
#include "bsp_gpio.h"
#include "bsp_uart.h"
#include "driverCrc16.h"
#include "bootLoader.h"
#include "systick.h"
#include "gd32f4xx_usart.h"
#include "gd32f4xx_gpio.h"
#include "gd32f4xx_rcu.h"
#include <stdio.h>

int fputc(int ch, FILE *f)
{
    usart_data_transmit(USART5, (uint8_t)ch);
    while (RESET == usart_flag_get(USART5, USART_FLAG_TBE))
        ;
    return ch;
}

void Init_Debug(void)
{
    /* enable GPIO clock */
    rcu_periph_clock_enable(RCU_GPIOC);

    /* enable USART clock */
    rcu_periph_clock_enable(RCU_USART5);

    /* configure the USART0 TX pin and USART0 RX pin */
    gpio_af_set(GPIOC, GPIO_AF_8, GPIO_PIN_6);
    gpio_af_set(GPIOC, GPIO_AF_8, GPIO_PIN_7);

    /* configure USART0 TX as alternate function push-pull */
    gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_6);
    gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);

    /* configure USART0 RX as alternate function push-pull */
    gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_7);
    gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);

    /* USART configure */
    usart_deinit(USART5);
    usart_baudrate_set(USART5, 115200U);
    usart_word_length_set(USART5, USART_WL_8BIT); // 8位数据
    usart_stop_bit_set(USART5, USART_STB_1BIT);   // 1位停止位
    usart_parity_config(USART5, USART_PM_NONE);
    usart_receive_config(USART5, USART_RECEIVE_ENABLE);
    usart_transmit_config(USART5, USART_TRANSMIT_ENABLE);
    usart_enable(USART5);

    // printf("a usart transmit test example!");
    // while(1);
}

int main(void)
{
    SystemCoreClockUpdate();
    // 初始化Core时钟
    systick_config();
    InitCRC();
    // 初始化GPIO并打开V3.3外设供电
    InitGpio();
    int i = 10;
    delay_1ms(500);
    // debug 需要usart5
    Init_Debug();
    printf("test");
    // 上面这些是debug加的
    SerialPutString("\r\nThanks for use this bootLoader\r\n");
    // 初始化串口
    InitSerial();
    while (i > 0)
    {
        PowerOnBmcPeriph();
        char str[64] = {0};
        sprintf(str, "\r\nWait for ESC key to enter IAP...remain %d s\r\n", i);
        SerialPutString(str);
        if (GetIAPIntper() == 1)
        // 如果获取到IAP请求中断则打印菜单进行IAP操作
        {
            Flash_IF_Init();
            PrintMenu();
            break;
        }
        delay_1ms(500);
        PowerOffBmcPeriph();
        delay_1ms(500);
        i--;
    }
    if (i <= 0)
    {
        // 如果无请求则跳转到APP启动
        SerialPutString("Run App...\r\n");
        RunApp();
    }

    while (1)
    {
    }
}
